home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / nr4timer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-30  |  4.2 KB  |  182 lines

  1. /* net/rom level 4 (transport) protocol timer management.
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "netrom.h"
  13. #include "nr4.h"
  14. #include <ctype.h>
  15.  
  16. #undef NR4DEBUG
  17.  
  18. unsigned Nr_timertype = 0;        /* default to binary exponential */
  19.  
  20. /* The ACK timer has expired without any data becoming available.
  21.  * Go ahead and send an ACK.
  22.  */
  23.  
  24. void
  25. nr4ackit(p)
  26. void *p ;
  27. {
  28.     struct nr4cb *cb  = (struct nr4cb *)p ;
  29.     struct nr4hdr rhdr ;
  30.  
  31. #ifdef NR4DEBUG
  32.     printf("ACKIT called.\n") ;
  33. #endif
  34.  
  35.     stop_timer(&cb->tack);  /* fixed N1BEE 920811 */
  36.     if (cb->qfull)              /* Are we choked? */
  37.         rhdr.opcode = NR4OPACK | NR4CHOKE ;
  38.     else
  39.         rhdr.opcode = NR4OPACK ;
  40.     rhdr.yourindex = cb->yournum ;
  41.     rhdr.yourid = cb->yourid ;
  42.     rhdr.u.ack.rxseq = cb->rxpected ;
  43.  
  44.     nr4sframe(cb->remote.node, &rhdr, NULLBUF) ;
  45. }
  46.  
  47. /* Called when one of the transmit timers has expired */
  48.  
  49. void
  50. nr4txtimeout(p)
  51. void *p ;
  52. {
  53.     struct nr4cb *cb = (struct nr4cb *)p ;
  54.     unsigned seq ;
  55.     struct nr4txbuf *t ;
  56.  
  57.     /* Sanity check */
  58.  
  59.     if (cb->state != NR4STCON)
  60.         return ;
  61.  
  62.     /* Scan through the send window looking for expired timers */
  63.     
  64.     for (seq = cb->ackxpected ;
  65.          nr4between(cb->ackxpected, seq, cb->nextosend) ;
  66.          seq = (seq + 1) & NR4SEQMASK) {
  67.         
  68.         t = &cb->txbufs[seq % cb->window] ;
  69.  
  70.         if (t->tretry.state == TIMER_EXPIRE) {
  71.             t->tretry.state = TIMER_STOP ;    /* So we don't do it again */
  72.  
  73.             if (t->retries == Nr4retries) {
  74.                 cb->dreason = NR4RTIMEOUT ;
  75.                 nr4state(cb, NR4STDISC) ;
  76.             }
  77.  
  78.             t->retries++ ;
  79.             
  80.             /* We keep track of the highest retry count in the window. */
  81.             /* If packet times out and its new retry count exceeds the *
  82.             /* max, we update the max and bump the backoff level.  This */
  83.             /* expedient is to avoid bumping the backoff level for every */
  84.             /* expiration, since with more than one timer we would back */
  85.             /* off way too fast (and at a rate dependent on the window */
  86.             /* size! */
  87.  
  88.             if (t->retries > cb->txmax) {
  89.                 cb->blevel++ ;
  90.                 cb->txmax = t->retries ;    /* update the max */
  91.             }
  92.             
  93.             nr4sbuf(cb,seq) ;    /* Resend buffer */
  94.         }
  95.      }
  96.     
  97. }
  98.  
  99. /* Connect/disconnect acknowledgement timeout */
  100.  
  101. void
  102. nr4cdtimeout(p)
  103. void *p ;
  104. {
  105.     struct nr4cb *cb = (struct nr4cb *)p ;
  106.     struct nr4hdr hdr ;
  107.  
  108.     switch(cb->state) {
  109.       case NR4STCPEND:
  110.           if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  111.             cb->dreason = NR4RTIMEOUT ;
  112.             nr4state(cb, NR4STDISC) ;        /* Give it up */
  113.         } else {
  114.             /* Set up header */
  115.             
  116.             hdr.opcode = NR4OPCONRQ ;
  117.             hdr.u.conreq.myindex = cb->mynum ;
  118.             hdr.u.conreq.myid = cb->myid ;
  119.             hdr.u.conreq.window = Nr4window ;
  120.             memcpy(hdr.u.conreq.user,cb->local.user,AXALEN) ;
  121.             memcpy(hdr.u.conreq.node,cb->local.node,AXALEN) ;
  122.  
  123.             /* Bump tries counter and backoff level, and restart timer */
  124.             /* We use a linear or binary exponential backoff. */
  125.             
  126.             cb->cdtries++ ;
  127.             cb->blevel++ ;
  128.  
  129.             if(Nr_timertype)
  130.                 /* linear */
  131.                 set_timer(&cb->tcd,dur_timer(&cb->tcd)+cb->srtt);
  132.             else
  133.                 /* exponential */
  134.                 set_timer(&cb->tcd,dur_timer(&cb->tcd)*2);
  135.  
  136.             start_timer(&cb->tcd) ;
  137.  
  138.             /* Send connect request packet */
  139.  
  140.             nr4sframe(cb->remote.node,&hdr, NULLBUF) ;
  141.         }
  142.         break ;
  143.         
  144.       case NR4STDPEND:
  145.           if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  146.             cb->dreason = NR4RTIMEOUT ;
  147.             nr4state(cb, NR4STDISC) ;        /* Give it up */
  148.         } else {
  149.             /* Format header */
  150.             
  151.             hdr.opcode = NR4OPDISRQ ;
  152.             hdr.yourindex = cb->yournum ;
  153.             hdr.yourid = cb->yourid ;
  154.  
  155.             /* Bump retry count and start timer */
  156.             /* We don't really need to be fancy here, since we */
  157.             /* should have a good idea of the round trip time by now. */
  158.             
  159.             cb->cdtries++ ;
  160.             start_timer(&cb->tcd) ;
  161.  
  162.             /* Send disconnect request packet */
  163.  
  164.             nr4sframe(cb->remote.node,&hdr, NULLBUF) ;
  165.         }
  166.         break ;
  167.     }
  168. }
  169.  
  170. /* The choke timer has expired.  Unchoke and kick. */
  171.  
  172. void
  173. nr4unchoke(p)
  174. void *p ;
  175. {
  176.     struct nr4cb *cb = (struct nr4cb *)p ;
  177.  
  178.     cb->choked = 0 ;
  179.     nr4output(cb) ;
  180. }
  181.  
  182.